package com.rightsidetech.activity.service.impl;

import com.gexin.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rightsidetech.activity.dto.request.*;
import com.rightsidetech.activity.dto.response.*;
import com.rightsidetech.activity.entity.*;
import com.rightsidetech.activity.mapper.*;
import com.rightsidetech.activity.service.ActCouponService;
import com.rightsidetech.commom.base.DelReq;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.utils.ByteUtil;
import com.rightsidetech.commom.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @Author: yhr
 * @Date: 2021-12-21 14:05
 */
@Service("actCouponService")
@Slf4j
public class ActCouponServiceImpl implements ActCouponService {
    @Resource
    private ActCouponBaseInfoMapper actCouponBaseInfoMapper;
    @Resource
    private ActCouponActivityMapper actCouponActivityMapper;
    @Resource
    private ActCouponActivityStatisMapper actCouponActivityStatisMapper;
    @Resource
    private ActCouponActivityCheckRecordMapper actCouponActivityCheckRecordMapper;
    @Resource
    private ActCouponActivityCodeMapper actCouponActivityCodeMapper;
    @Resource
    private ActCouponGetRecordMapper actCouponGetRecordMapper;
    @Resource
    private ActCouponUsedRecordMapper actCouponUsedRecordMapper;
    @Resource
    private ActActivityAuditRecordMapper actActivityAuditRecordMapper;

    @Override
    public ResponseData<PageInfo<ActCouponBaseResp>> page(ActCouponBasePageReq req) {
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<ActCouponBaseResp> page = actCouponBaseInfoMapper.page(req);
        return ResponseData.success(new PageInfo<>(page));
    }

    @Override
    public ResponseData saveCouponBase(ActCouponBaseSaveReq req,Long loginId, String loginName) {
        ActCouponBaseInfo byName = actCouponBaseInfoMapper.selectByName(req.getCouponName());
        if (!ObjectUtils.isEmpty(byName)){
            return ResponseData.fail("基础优惠券名称重复");
        }
        ActCouponBaseInfo couponBase = new ActCouponBaseInfo();
        couponBase.setCouponName(req.getCouponName());
        couponBase.setCouponType(req.getCouponType());
        couponBase.setAmount(req.getAmount());
        couponBase.setCreaterId(loginId);
        couponBase.setCreatedAt(new Date());
        couponBase.setCreaterName(loginName);
        return ResponseData.success(actCouponBaseInfoMapper.insertSelective(couponBase));
    }

    @Override
    public ResponseData updateCouponBase(ActCouponBaseUpdateReq req, Long loginId,String loginName) {
        ActCouponBaseInfo base = actCouponBaseInfoMapper.selectByPrimaryKey(req.getCouponBaseId());
        if (ObjectUtils.isEmpty(base)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        //判断是否已经关联生成活动
        int activityCount = actCouponActivityMapper.countByCouponBaseId(req.getCouponBaseId());
        if(activityCount > 0){
            return ResponseData.fail(CodeIdEnum.ActivityRelationBaseCoupon);
        }

        ActCouponBaseInfo couponBase = new ActCouponBaseInfo();
        couponBase.setId(req.getCouponBaseId());
        couponBase.setCouponName(req.getCouponName());
        couponBase.setCouponType(req.getCouponType());
        couponBase.setAmount(req.getAmount());
        couponBase.setUpdaterId(loginId);
        couponBase.setUpdatedAt(new Date());
        couponBase.setUpdaterName(loginName);
        return ResponseData.success(actCouponBaseInfoMapper.updateByPrimaryKeySelective(couponBase));
    }

    @Override
    public ResponseData delCouponSBase(DelReq req,Long loginInfoId,String loginName) {
        ActCouponBaseInfo base = actCouponBaseInfoMapper.selectByPrimaryKey(req.getId());
        if (ObjectUtils.isEmpty(base)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        //判断是否已经关联生成活动
        int activityCount = actCouponActivityMapper.countByCouponBaseId(req.getId());
        if(activityCount > 0){
            return ResponseData.fail(CodeIdEnum.ActivityRelationBaseCoupon);
        }
        ActCouponBaseInfo couponBase = new ActCouponBaseInfo();
        couponBase.setId(req.getId());
        couponBase.setIsDeleted((byte) 1);
        couponBase.setUpdaterId(loginInfoId);
        couponBase.setUpdatedAt(new Date());
        couponBase.setUpdaterName(loginName);
        return ResponseData.success(actCouponBaseInfoMapper.updateByPrimaryKeySelective(couponBase));
    }

    @Override
    public ResponseData<PageInfo<ActCouponActivityPageResp>> activityPage(ActCouponActivityPageReq req) {
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<ActCouponActivityPageResp> resps = actCouponActivityMapper.activityPage(req);
        return ResponseData.success(new PageInfo(resps));
    }

    @Override
    public ResponseData<ActCouponActivityInfoResp> activityInfo(Long activityId) {
        ActCouponActivityInfoResp infoResp = actCouponActivityMapper.activityInfo(activityId);
        if (ObjectUtils.isEmpty(infoResp)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        //查询门店驳回记录
        String rejectReasons = actCouponActivityCheckRecordMapper.findRejectReasonByActivityId(activityId);

        if(!StringUtils.isEmpty(rejectReasons)){
            infoResp.setRejectReasons(rejectReasons);
        }

        return ResponseData.success(infoResp);
    }

    @Override
    public ActCouponActivity getActivityByActivityId(Long activityId) {
        return actCouponActivityMapper.selectByPrimaryKey(activityId);
    }

    @Override
    public ResponseData saveActivity(ActCouponActivitySaveReq req, Long loginId, String loginName) {
        String endDate = req.getEndTime()+" 23:59:59";
        if (new Date().after(DateUtil.getDate(endDate, "yyyy-MM-dd HH:mm:ss"))){
            return ResponseData.fail("结束日期不能小于当前日期");
        }
        ActCouponActivity couponActivity = actCouponActivityMapper.selectByName(req.getActivityName());
        if (!ObjectUtils.isEmpty(couponActivity)){
            return ResponseData.fail("活动名称重复");
        }

        ActCouponActivity activity = new ActCouponActivity();
        activity.setActivityName(req.getActivityName());
        activity.setActivityNo(createCode(1));
        activity.setCouponBaseId(req.getCouponBaseId());
        activity.setMinConsumeAmount(req.getMinConsumeAmount());
        activity.setMaxDiscountAmount(req.getMaxDiscountAmount());
        activity.setTotalQuantity(req.getTotalQuantity());
        activity.setGetQuantity(req.getGetQuantity());
        activity.setPicture(req.getPicture());
        activity.setTarget(req.getTarget());
        activity.setLevel(req.getLevel());
        activity.setStartTime(new Date());
        activity.setEndTime(DateUtil.getDate(endDate, "yyyy-MM-dd HH:mm:ss"));
        activity.setRuleDetails(req.getRuleDetails());
        activity.setCreaterId(loginId);
        activity.setCreatedAt(new Date());
        activity.setCreaterName(loginName);
        activity.setUseScope(req.getUseScope());
        activity.setAreaIds(req.getAreaIds());
        activity.setAgentIds(req.getAgentIds());
        actCouponActivityMapper.insertSelective(activity);

        return ResponseData.success();
    }

    @Override
    public ResponseData updateActivity(ActCouponActivityUpdateReq req, Long loginId,String loginName) {
        String endDate = req.getEndTime()+" 23:59:59";
        if (new Date().after(DateUtil.getDate(endDate, "yyyy-MM-dd HH:mm:ss"))){
            return ResponseData.fail("结束日期不能小于当前日期");
        }
        ActCouponActivity activity = actCouponActivityMapper.selectByPrimaryKey(req.getActivityId());
        if (ObjectUtils.isEmpty(activity)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        if (activity.getStatus() != 0 && activity.getStatus() != 1 && activity.getStatus() != 3){
            return ResponseData.fail("已通过审核无法修改");
        }

        ActCouponActivity couponActivity = actCouponActivityMapper.selectByName(req.getActivityName());
        if(!StringUtils.isEmpty(couponActivity) && !couponActivity.getId().equals(req.getActivityId())){
            return ResponseData.fail("活动名称重复");
        }

        activity.setId(req.getActivityId());
        activity.setActivityName(req.getActivityName());
        activity.setCouponBaseId(req.getCouponBaseId());
        activity.setMinConsumeAmount(req.getMinConsumeAmount());
        activity.setMaxDiscountAmount(req.getMaxDiscountAmount());
        activity.setTotalQuantity(req.getTotalQuantity());
        activity.setGetQuantity(req.getGetQuantity());
        activity.setPicture(req.getPicture());
        activity.setTarget(req.getTarget());
        activity.setLevel(req.getLevel());
        activity.setStartTime(new Date());
//        String endDate = req.getEndTime()+" 23:59:59";
        activity.setEndTime(DateUtil.getDate(endDate, "yyyy-MM-dd HH:mm:ss"));
        activity.setRuleDetails(req.getRuleDetails());
        activity.setUpdaterId(loginId);
        activity.setUpdatedAt(new Date());
        if (activity.getStatus() == 3){
            activity.setStatus((byte) 0);
        }
        activity.setUpdaterName(loginName);
        activity.setUseScope(req.getUseScope());
        activity.setAgentIds(req.getAgentIds());
        activity.setAreaIds(req.getAreaIds());
        actCouponActivityMapper.updateByPrimaryKeySelective2(activity);

        return ResponseData.success();
    }

    @Override
    public ResponseData reject(ActCouponActivityStatusReq req,Long loginId,String loginName) {
        if (req.getStatus() == 3 && StringUtils.isEmpty(req.getRejectReason())){
            return ResponseData.fail("审核原因不能为空");
        }
        ActCouponActivity couponActivity = actCouponActivityMapper.selectByPrimaryKey(req.getActivityId());
        if (ObjectUtils.isEmpty(couponActivity)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        if (1 != couponActivity.getStatus()){
            return ResponseData.fail("该优惠活动未处于审核中");
        }
        //插入审核记录
        ActCouponActivityCheckRecord checkRecord = new ActCouponActivityCheckRecord();
        checkRecord.setCouponActivityId(req.getActivityId());
        checkRecord.setRejectReason(req.getRejectReason());
        checkRecord.setStatus(req.getStatus());
        checkRecord.setCreatedAt(new Date());
        checkRecord.setCreaterId(loginId);
        checkRecord.setCreaterName(loginName);
        actCouponActivityCheckRecordMapper.insertSelective(checkRecord);

        //插入营销审核
        ActActivityAuditRecord activityAuditRecord = new ActActivityAuditRecord();
        activityAuditRecord.setActivityId(req.getActivityId());
//        activityAuditRecord.setAuditStatus(req.getStatus());
        if(req.getStatus() == 2){
            activityAuditRecord.setAuditStatus((byte) 1);
        }else{
            activityAuditRecord.setAuditStatus((byte) -1);
        }
        activityAuditRecord.setAuditContent(req.getRejectReason());
        activityAuditRecord.setCreatedName(loginName);
        activityAuditRecord.setCreatedAt(new Date());
        activityAuditRecord.setCreaterId(loginId);
        activityAuditRecord.setActivityName("优惠券活动");
        activityAuditRecord.setEventName(couponActivity.getActivityName());
        actActivityAuditRecordMapper.insertSelective(activityAuditRecord);

        //修改优惠券活动状态
        ActCouponActivity activity = new ActCouponActivity();
        activity.setId(req.getActivityId());
        activity.setStatus(req.getStatus());
        activity.setUpdatedAt(new Date());
        activity.setUpdaterId(loginId);
        activity.setUpdaterName(loginName);
        actCouponActivityMapper.updateByPrimaryKeySelective(activity);

        return ResponseData.success();
    }

    @Override
    public ResponseData check(Long id,Long loginId,String loginName) {
        ActCouponActivity couponActivity = actCouponActivityMapper.selectByPrimaryKey(id);
        if (ObjectUtils.isEmpty(couponActivity)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        if (0 != couponActivity.getStatus() && 3 != couponActivity.getStatus()){
            return ResponseData.fail("该优惠活动不可发起审核");
        }
        ActCouponActivity activity = new ActCouponActivity();
        activity.setId(id);
        activity.setStatus((byte) 1);
        activity.setUpdatedAt(new Date());
        activity.setUpdaterId(loginId);
        activity.setUpdaterName(loginName);
        actCouponActivityMapper.updateByPrimaryKeySelective(activity);
        return ResponseData.success();
    }

    @Override
    public ResponseData delActivity(Long id,Long loginId,String loginName) {
        ActCouponActivity couponActivity = actCouponActivityMapper.selectByPrimaryKey(id);
        if (ObjectUtils.isEmpty(couponActivity)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        if (couponActivity.getStatus() == 4){
            return ResponseData.fail("优惠券已发放无法删除");
        }

        ActCouponActivity couponActivity1 = new ActCouponActivity();
        couponActivity1.setId(id);
        couponActivity1.setUpdatedAt(new Date());
        couponActivity1.setUpdaterId(loginId);
        couponActivity1.setUpdaterName(loginName);
        couponActivity1.setIsDeleted((byte) 1);

        return ResponseData.success(actCouponActivityMapper.updateByPrimaryKeySelective(couponActivity1));
    }

    @Override
    public ResponseData generate(Long id,Long loginId,String loginName) {
//        ActCouponActivityStatis statis = new ActCouponActivityStatis();
        ActCouponActivity couponActivity = actCouponActivityMapper.selectByPrimaryKey(id);
        if(StringUtils.isEmpty(couponActivity)){
            return ResponseData.fail("活动不存在");
        }
        if (couponActivity.getStatus() == 4){
            return ResponseData.fail("优惠券已发放");
        }
        if (couponActivity.getStatus() != 2){
            return ResponseData.fail("此活动优惠券未达到发放要求");
        }

        ActCouponActivity activity = new ActCouponActivity();
        activity.setId(couponActivity.getId());
        activity.setUpdatedAt(new Date());
        activity.setUpdaterId(loginId);
        activity.setUpdaterName(loginName);
        activity.setStatus((byte) 4);

        actCouponActivityMapper.updateByPrimaryKeySelective(activity);

        ActCouponActivityCode code = new ActCouponActivityCode();
        code.setCouponActivityId(couponActivity.getId());
        code.setStatus((byte) 0);
        code.setCreatedAt(new Date());
        //取到代理商信息, 查询有多少门店


        for (int i = 0; i < couponActivity.getTotalQuantity(); i++) {
            code.setCode(createCode(i));
            while (actCouponActivityCodeMapper.selectCountCodeByCode(code.getCode()) > 0){
                code.setCode(createCode(i + 50));
                log.info("避免重复的code={}",code.getCode());
            }
            actCouponActivityCodeMapper.insertSelective(code);
        }

/*        statis.setReceiveNum(0L);
        statis.setCouponActivityId(couponActivity.getId());
        statis.setQuantity(couponActivity.getTotalQuantity());
        statis.setUseNum(Long.valueOf(0));
        statis.setTotalDiscountAmount(new BigDecimal(0));
        statis.setTotalPayableAmount(new BigDecimal(0));
        statis.setTotalPayAmount(new BigDecimal(0));
        statis.setCreatedAt(new Date());
        actCouponActivityStatisMapper.insertSelective(statis);*/

        return ResponseData.success();
    }

    @Override
    public ResponseData<PageInfo<ActReceivePageResp>> receivePage(ActUserCouponReq req) {
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<ActReceivePageResp> page = actCouponGetRecordMapper.receivePage(req);
        return ResponseData.success(new PageInfo<>(page));
    }

    @Override
    public ResponseData<PageInfo<ActCouponCountPageResp>> couponCount(ActCouponCountReq req) {
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<ActCouponCountPageResp> page = actCouponActivityStatisMapper.couponCount(req);
        return ResponseData.success(new PageInfo<>(page));
    }

    @Override
    public ResponseData couponClose(Long id,Long loginId,String loginName) {
        ActCouponActivity actCouponActivity = actCouponActivityMapper.selectByPrimaryKey(id);
        if (ObjectUtils.isEmpty(actCouponActivity)){
            return ResponseData.fail(CodeIdEnum.EMPTY_DATA);
        }
        if (actCouponActivity.getStatus() == 6){
            return ResponseData.fail("已作废,请勿重复操作");
        }
        if(actCouponActivity.getStatus() != 2 && actCouponActivity.getStatus() != 4){
            return ResponseData.fail("活动状态不正确");
        }
        ActCouponActivity activity = new ActCouponActivity();
        activity.setId(id);
        activity.setStatus((byte) 6);
        activity.setUpdaterId(loginId);
        activity.setUpdaterName(loginName);
        activity.setUpdatedAt(new Date());

        actCouponActivityMapper.updateByPrimaryKeySelective(activity);
        //修改已领取的优惠券状态为作废
        actCouponGetRecordMapper.updateStatusByActivityIdAndStatus(id);


        return ResponseData.success();
    }


    @Override
    public int selectCount(Long storeId, Long agentId) {
        List<ActCouponActivity> activityList = actCouponActivityMapper.selectStoreUsedActivity();
        if(activityList.isEmpty()){
            return 0;
        }
        for(ActCouponActivity activity:activityList){
            String useScope = activity.getUseScope();
            if(StringUtils.isEmpty(useScope)){
                continue;
            }
            List<Long> list = JSONArray.parseArray(useScope,Long.class);
            boolean flag = list.contains(agentId);
            if(!flag){
                continue;
            }
            int storeCount = actCouponUsedRecordMapper.selectCountByActivityIdAndStoreId(activity.getId(),storeId);
            if(storeCount <= activity.getGetQuantity()){
                return 1;
            }
        }
        return 0;

    }

    @Override
    public void updateStatusByEndTime() {
        //查询是否存在过期的优惠券
        List<ActCouponActivity> list = actCouponActivityMapper.selectByStatusAndEndTime();
        if(!list.isEmpty()){
            for(ActCouponActivity activity:list){
                ActCouponActivity activity1 = new ActCouponActivity();
                activity1.setId(activity.getId());
                activity1.setStatus((byte) 5);
                activity1.setUpdatedAt(new Date());
                actCouponActivityMapper.updateByPrimaryKeySelective(activity1);
            }
        }
    }

    @Override
    public ResponseData<PageInfo<ActUserCouponResp>> selectStoreCoupon(ActUserCouponReq req) {
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<ActUserCouponResp> page = actCouponGetRecordMapper.selectList(req);
        return ResponseData.success(new PageInfo<>(page));
    }

    @Override
    public ResponseData<PageInfo<ActUserGetCouponResp>> selectUserCoupon(ActUserCouponReq req) {
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<ActUserGetCouponResp> page = actCouponGetRecordMapper.selectUserList(req);
        return ResponseData.success(new PageInfo<>(page));
    }

    @Override
    public ResponseData<PageInfo<ActEntityCouponResp>> selectEntityCoupon(ActEntityCouponReq req) {
        PageHelper.startPage(req.getPageNo(),req.getPageSize());
        List<ActEntityCouponResp> page = actCouponActivityCodeMapper.selectEntityCoupon(req);
        return ResponseData.success(new PageInfo<>(page));
    }

    @Override
    public ActCouponActivity findByid(Long activityId) {
        return actCouponActivityMapper.selectByPrimaryKey(activityId);
    }

    @Override
    public List<Long> findStatisActivityId() {
        return actCouponActivityMapper.findStatisActivityId();
    }

    @Override
    public Long findCountByActivityId(Long activityId,Byte status) {
        return actCouponGetRecordMapper.selectByActivityId(activityId,status);
    }

    @Override
    public ResponseData saveActivityStatis(ActCouponActivityStatis statis) {

        ActCouponActivityStatis activityStatis = actCouponActivityStatisMapper.selectByAcId(statis.getCouponActivityId());
        if(!StringUtils.isEmpty(activityStatis)){
            statis.setId(activityStatis.getId());
            statis.setUpdatedAt(new Date());
            actCouponActivityStatisMapper.updateByPrimaryKeySelective(statis);
        }else{
            statis.setCreatedAt(new Date());
            actCouponActivityStatisMapper.insertSelective(statis);
        }

        return ResponseData.success();
    }

    private String createCode(int i){
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        String date = df.format(new Date());
        String increase = ByteUtil.autoGenericCode(String.valueOf(i), 4);
        String dom = ByteUtil.autoGenericCode(String.valueOf(new Random().nextInt(99)), 2);
        String s = date+increase+dom;
        String bcc = ByteUtil.getBCC(s);
        return s+bcc;
    }
}
